package com.lujianfei.netease_android_viewpager2.widget

import android.util.DisplayMetrics
import android.view.View
import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import kotlin.math.min

class CustomPagerSnapHelper(recyclerView: RecyclerView, flingDuration: Int) : PagerSnapHelper() {

    companion object {
        const val MILLISECONDS_PER_INCH = 100
    }

    var mIsFakeDragging: (() -> Boolean)? = null
    var mRecyclerView: RecyclerView? = null
    var mFlingDuration = 100

    init {
        mRecyclerView = recyclerView
        mFlingDuration = flingDuration
    }

    override fun createSnapScroller(layoutManager: RecyclerView.LayoutManager?): LinearSmoothScroller? {
        mRecyclerView?.let { mRecyclerView ->
            return object : LinearSmoothScroller(mRecyclerView.context) {
                override fun onTargetFound(targetView: View, state: RecyclerView.State, action: Action) {
                    val snapDistances = calculateDistanceToFinalSnap(mRecyclerView.layoutManager!!,
                            targetView)
                    val dx = snapDistances!![0]
                    val dy = snapDistances[1]
                    val time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)))
                    if (time > 0) {
                        action.update(dx, dy, time, mDecelerateInterpolator)
                    }
                }

                override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
                    return MILLISECONDS_PER_INCH.toFloat() / displayMetrics.densityDpi
                }

                override fun calculateTimeForScrolling(dx: Int): Int {
                    return min(mFlingDuration, super.calculateTimeForScrolling(dx))
                }
            }
        } ?: let {
            return null
        }
    }

    override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {
        mIsFakeDragging?.let {
            return if (it()) null else super.findSnapView(layoutManager)
        } ?: let {
            return super.findSnapView(layoutManager)
        }
    }
}